﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Microsoft.Xna.Framework.Graphics;
using Microsoft.Xna.Framework;
using PloobsEngine.Modelo;
using PloobsEngine;

namespace Etapa1.ModelDescription
{
    public class ExtractModelInformations
    {           

        public void GenerateBuffers(List<Triangulo> triangulos, List<Vertice> vertices, out VertexBuffer vertexBuffer, out IndexBuffer indexBuffer, out VertexDeclaration vd)
        {
            VertexPositionNormalTexture[] vertexData  = new VertexPositionNormalTexture[vertices.Count] ;
            List<int> indices = new List<int>();
            for (int i = 0; i < vertices.Count; i++)
			{
                vertexData[i] = vertices[i].VertexInfo;
			}

            foreach (var item in triangulos)
            {
                foreach (var vt in item.Vertices)
                {
                    indices.Add(vt.PosInVertexList);   
                }
            }

            vertexBuffer = new VertexBuffer(EngineStuff.GraphicsDevice, vertexData.Count() * VertexPositionNormalTexture.SizeInBytes, BufferUsage.WriteOnly);
            vertexBuffer.SetData<VertexPositionNormalTexture>(vertexData);

            indexBuffer = new IndexBuffer(EngineStuff.GraphicsDevice, typeof(int), indices.Count, BufferUsage.WriteOnly);
            indexBuffer.SetData<int>(indices.ToArray());

            vd = new VertexDeclaration(EngineStuff.GraphicsDevice, VertexPositionNormalTexture.VertexElements);
        }

        public void ExtractInfos(IModelo model, out List<VertexPositionNormalTexture> vertices,out List<int> indices)
        {
            indices = new List<int>();
            vertices = new List<VertexPositionNormalTexture>();
            Matrix[] bones_ = model.getBonesTransformation();            
            for (int i = 0; i < model.MeshNumber; i++)
            {
                Matrix xform;
                xform = bones_[model.GetParentBoneIndex(i)];

                BatchInformation[] bi = model.GetBatchInformation(i);
                for (int j = 0; j < bi.Length; j++)
                {
                    int offset = vertices.Count;
                    VertexPositionNormalTexture[] vpnt = new VertexPositionNormalTexture[bi[j].NumVertices];                    
                    model.GetVertexBuffer(i).GetData<VertexPositionNormalTexture>(bi[j].StreamOffset + bi[j].BaseVertex * bi[j].VertexStride, vpnt, 0, bi[j].NumVertices, bi[j].VertexStride);                    
                    //Vector3[] a = new Vector3[mmp.NumVertices];
                    //mm.VertexBuffer.GetData<Vector3>(mmp.StreamOffset + mmp.BaseVertex * mmp.VertexStride,a, 0, mmp.NumVertices, mmp.VertexStride);                    
                    for (int k = 0; k != vpnt.Length; ++k)
                    {
                        Vector3.Transform(ref vpnt[k].Position, ref xform, out vpnt[k].Position);
                    }
                    vertices.AddRange(vpnt);

                    if (model.GetIndexBuffer(i).IndexElementSize == IndexElementSize.SixteenBits)
                    {
                        short[] s = new short[bi[j].PrimitiveCount * 3];
                        model.GetIndexBuffer(i).GetData<short>(bi[j].StartIndex * 2, s, 0, bi[j].PrimitiveCount * 3);
                        for (int k = 0; k != bi[j].PrimitiveCount; ++k)
                        {
                            indices.Add(s[k * 3 + 2] + offset);
                            indices.Add(s[k * 3 + 1] + offset);
                            indices.Add(s[k * 3 + 0] + offset);
                        }
                    }
                    else
                    {
                        int[] s = new int[bi[j].PrimitiveCount * 3];
                        model.GetIndexBuffer(i).GetData<int>(bi[j].StartIndex * 2, s, 0, bi[j].PrimitiveCount * 3);
                        for (int k = 0; k != bi[j].PrimitiveCount; ++k)
                        {
                            indices.Add(s[k * 3 + 2] + offset);
                            indices.Add(s[k * 3 + 1] + offset);
                            indices.Add(s[k * 3 + 0] + offset);
                        }
                    }
                }
            }
        }


        public void ExtractInfos(IndexBuffer indexBuffer, VertexBuffer vertexBuffer, int primitiveCount, int vertexCount, int vertexStride, out List<VertexPositionNormalTexture> vertices, out List<int> indices)
        {
                    indices = new List<int>();
                    vertices = new List<VertexPositionNormalTexture>();
                    
                    VertexPositionNormalTexture[] vpnt = new VertexPositionNormalTexture[vertexCount];
                    vertexBuffer.GetData<VertexPositionNormalTexture>(0, vpnt, 0, vertexCount, vertexStride);
                    vertices.AddRange(vpnt);

                    if (indexBuffer.IndexElementSize == IndexElementSize.SixteenBits)
                    {
                        short[] s = new short[primitiveCount * 3];
                        indexBuffer.GetData<short>(0, s, 0, primitiveCount * 3);
                        foreach (var item in s)
                        {
                            indices.Add(item);
                        }
                    }
                    else
                    {
                        int[] s = new int[primitiveCount * 3];
                        indexBuffer.GetData<int>(0, s, 0, primitiveCount * 3);
                        foreach (var item in s)
                        {
                            indices.Add(item);
                        }
                    }                                        
        }

    }
}
